package com.daguchuangyi.erp_android.manager;

import android.support.v4.util.Pair;

import com.daguchuangyi.erp_android.manager.networkservice.ProductService;
import com.daguchuangyi.erp_android.model.product.Parameter;
import com.daguchuangyi.erp_android.productlist.parametersetting.ParamsSectionWrapper;
import com.jude.utils.JUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by lijianjian on 2018/3/20.
 */

public class ParameterManager {
    public static final int ID_PRODUCT_IMAGE_DEFAULT = -46;
    public static final int ID_CAD_IMAGE_OPTIONS = -43;
    public static final int ID_SAMPLE_OPTIONS = -44;
    public static final int ID_STOCK_OPTIONS = -45;


    public static final int TYPE_SELECT = 1;
    public static final int TYPE_DATE = 2;
    public static final int TYPE_NUMBER = 3;
    public static final int TYPE_NORMAL = 4;

    private static ParameterManager sInstance;

    //    private String mParamsCheckContent = "";
    private Set<Parameter> mParametersChecked = new TreeSet<>();
    private Set<Integer> mLocalParamsCheckedSet = new HashSet<>();
    //    private HashMap<Integer, Parameter> mParamsCheckStatus = new HashMap<>();
    private Set<OnParamsChangeListener> mOnParamsChangeListenerList = new HashSet<>();
    private HashMap<Integer, ParamCheckStatus> mParamsCheckStatus = new HashMap<>();

//    private Pair<ParamsSectionWrapper, ParamsSectionWrapper> mParameterPair;

    public void addOnParamsChangeListener(OnParamsChangeListener listener) {
        mOnParamsChangeListenerList.add(listener);
    }

    public void removeOnParamsChangeListener(OnParamsChangeListener listener) {
        mOnParamsChangeListenerList.remove(listener);
    }

    public static synchronized ParameterManager getInstance() {
        if (sInstance == null) {
            synchronized (ParameterManager.class) {
                sInstance = new ParameterManager();
            }
        }
        return sInstance;
    }

    private ParameterManager() {
    }

    public void setParameterCheck(Set<Parameter> parameters, Set<Integer> localParamsCheckedSet) {
        mParametersChecked.clear();
        mParametersChecked.addAll(parameters);
        mLocalParamsCheckedSet.clear();
        mLocalParamsCheckedSet.addAll(localParamsCheckedSet);

        Observable.just(parameters)
                .flatMapIterable(parameters1 -> parameters1)
                .flatMap(parameter -> Observable.just(parameter.getId()))
                .toList()
                .flatMap(new Func1<List<Integer>, Observable<?>>() {
                    @Override
                    public Observable<?> call(List<Integer> integers) {
                        Map<String, Object> bodyMap = new HashMap<>();
                        bodyMap.put("parameterIds", integers);
                        return NetworkManager.getInstance().getRetrofit().create(ProductService.class)
                                .updateParameters(bodyMap);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Object>() {
                    @Override
                    public void call(Object o) {
                        JUtils.Log("upload parameter successfully.");
                        for (OnParamsChangeListener listener : mOnParamsChangeListenerList) {
                            listener.onParamChanged();
                        }
                    }
                }, throwable -> {
                    JUtils.Log("upload parameter error : " + throwable.getMessage());
                    throwable.printStackTrace();
                });


    }

    public Map<Integer, ParamCheckStatus> getParamsCheckStatus() {
        return mParamsCheckStatus;
    }

    public void setParamsCheckStatus(Map<Integer, ParamCheckStatus> paramsCheckStatus) {
        mParamsCheckStatus.clear();
        if (paramsCheckStatus != null) {
            mParamsCheckStatus.putAll(paramsCheckStatus);
        }
    }

    public Set<Parameter> getParametersChecked() {
        return mParametersChecked;
    }

    public Set<Integer> getLocalParamsCheckedSet() {
        return mLocalParamsCheckedSet;
    }

    public boolean isChecked(Parameter parameter) {
        return mParametersChecked.contains(parameter);
    }

    public Observable<Pair<ParamsSectionWrapper, ParamsSectionWrapper>> listParams(boolean forceRefresh) {
//        if (!forceRefresh && mParameterPair != null) {
//            return Observable.just(mParameterPair);
//        }
        return NetworkManager.getInstance().getRetrofit().create(ProductService.class)
                .listParameterSetting()
                .flatMap(parameterWrapper -> {

                    ParamsSectionWrapper defalutWrapper = new ParamsSectionWrapper();
                    defalutWrapper.setnSectiongWrapperName("默认参数");
                    Parameter imageParams = new Parameter();
                    imageParams.setId(ID_PRODUCT_IMAGE_DEFAULT);
                    imageParams.setName("商品图片");
                    List<Parameter> defaultParams = new ArrayList<>();
                    defaultParams.add(imageParams);
                    defalutWrapper.setParameters(defaultParams);

                    ParamsSectionWrapper optionWrapper = new ParamsSectionWrapper();
                    optionWrapper.setnSectiongWrapperName("可选参数");

                    List<Parameter> optionParameterList = parameterWrapper.getParameters();
                    Parameter stockParam = new Parameter();
                    stockParam.setName("仓储");
                    stockParam.setId(ID_STOCK_OPTIONS);
                    optionParameterList.add(0, stockParam);

                    Parameter sampleParam = new Parameter();
                    sampleParam.setName("样品库");
                    sampleParam.setId(ID_SAMPLE_OPTIONS);
                    optionParameterList.add(0, sampleParam);

                    Parameter CADParam = new Parameter();
                    CADParam.setName("CAD图片");
                    CADParam.setId(ID_CAD_IMAGE_OPTIONS);
                    optionParameterList.add(0, CADParam);
                    optionWrapper.setParameters(optionParameterList);
                    return Observable.just(new Pair<>(defalutWrapper, optionWrapper));
                });
//                .doOnNext(paramsSectionWrapperPair -> mParameterPair = paramsSectionWrapperPair);
    }

    public void clearParamsCheckStatus() {
        mParamsCheckStatus.clear();
    }

    public void clear() {

        //    private String mParamsCheckContent = "";
//        private Set<Parameter> mParametersChecked = new TreeSet<>();
//        private Set<Integer> mLocalParamsCheckedSet = new HashSet<>();
//        private HashMap<Integer, String> mParamsCheckStatus = new HashMap<>();
//        private Set<OnParamsChangeListener> mOnParamsChangeListenerList = new HashSet<>();
//
//        private Pair<ParamsSectionWrapper, ParamsSectionWrapper> mParameterPair;
        if (mParametersChecked != null) {
            mParametersChecked.clear();
        }
        if (mLocalParamsCheckedSet != null) {
            mLocalParamsCheckedSet.clear();
        }
        if (mParamsCheckStatus != null) {
            mParamsCheckStatus.clear();
        }
        if (mOnParamsChangeListenerList != null) {
            mOnParamsChangeListenerList.clear();
        }
    }

    public interface OnParamsChangeListener {
        public void onParamChanged();
    }

    public static class ParamCheckStatus {
        private Set<String> mOptionsCheck;
        private int mId;
        private String mMax;
        private String mMin;
        private int mType;

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            ParamCheckStatus that = (ParamCheckStatus) o;

            return mId == that.mId;
        }

        @Override
        public int hashCode() {
            return mId;
        }

        public Set<String> getOptionsCheck() {
            if (mOptionsCheck == null) {
                return new HashSet<>();
            }
            return mOptionsCheck;
        }

        public void setOptionsCheck(Set<String> optionsCheck) {
            mOptionsCheck = optionsCheck;
        }

        public int getId() {
            return mId;
        }

        public void setId(int id) {
            mId = id;
        }

        public int getType() {
            return mType;
        }

        public void setType(int type) {
            mType = type;
        }

        public String getMax() {
            return mMax;
        }

        public void setMax(String max) {
            mMax = max;
        }

        public String getMin() {
            return mMin;
        }

        public void setMin(String min) {
            mMin = min;
        }
    }
}
